package com.maxd.service.userinfo;

import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import com.fasterxml.jackson.databind.JsonNode;
import com.getui.push.v2.sdk.ApiHelper;
import com.getui.push.v2.sdk.GtApiConfiguration;
import com.getui.push.v2.sdk.api.PushApi;
import com.getui.push.v2.sdk.common.ApiResult;
import com.getui.push.v2.sdk.dto.req.Audience;
import com.getui.push.v2.sdk.dto.req.message.PushChannel;
import com.getui.push.v2.sdk.dto.req.message.PushDTO;
import com.getui.push.v2.sdk.dto.req.message.PushMessage;
import com.getui.push.v2.sdk.dto.req.message.android.GTNotification;
import com.getui.push.v2.sdk.dto.req.message.ios.Alert;
import com.getui.push.v2.sdk.dto.req.message.ios.Aps;
import com.getui.push.v2.sdk.dto.req.message.ios.IosDTO;
import com.gexin.rp.sdk.base.IPushResult;
import com.gexin.rp.sdk.base.impl.SingleMessage;
import com.gexin.rp.sdk.base.impl.Target;
import com.gexin.rp.sdk.exceptions.RequestException;
import com.gexin.rp.sdk.http.IGtPush;
import com.gexin.rp.sdk.template.NotificationTemplate;
import com.gexin.rp.sdk.template.style.Style0;
import com.github.qcloudsms.SmsSingleSender;
import com.github.qcloudsms.SmsSingleSenderResult;
import com.github.qcloudsms.httpclient.HTTPException;
import com.google.common.collect.Maps;
import com.maxd.adapter.LoginUserHolder;
import com.maxd.bean.user.AdjustPromotePointReq;
import com.maxd.component.sequence.SeqTools;
import com.maxd.constants.PPointScene;
import com.maxd.error.DescribeException;
import com.maxd.error.ExceptionEnum;
import com.maxd.error.Result;
import com.maxd.error.ResultUtil;
import com.maxd.model.*;
import com.maxd.respository.PromotePointRecordRepository;
import com.maxd.respository.common.CommonRepository;
import com.maxd.respository.msg.MsgJpaRepository;
import com.maxd.respository.token.TokenJpaRepository;
import com.maxd.respository.token.TokenRepository;
import com.maxd.respository.userinfo.UserJpaRepository;
import com.maxd.respository.userinfo.UserRepository;
import com.maxd.service.jifen.IJiFenService;
import com.maxd.service.message.IMessageService;
import com.maxd.service.wx.AccountService;
import com.maxd.utils.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import weixin.popular.bean.message.templatemessage.TemplateMessageItem;
import weixin.popular.bean.user.User;
import weixin.popular.util.JsonUtil;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigDecimal;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 用户的service实现类
 */
@Service
@Slf4j
public class UserServiceImpl implements IUserService {
    private Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
    @Autowired
    private UserJpaRepository userJpaRepository;
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private TokenJpaRepository tokenJpaRepository;
    @Autowired
    private TokenRepository tokenRepository;
    @Autowired
    private MsgJpaRepository msgJpaRepository;
    @Autowired
    private AccountService accountService;
    @Autowired
    private CommonRepository commonRepository;
    @Autowired
    private IMessageService iMessageService;
    private int number = 1;
    @Autowired
    private IJiFenService jiFenService;

    @Autowired
    private PromotePointRecordRepository promotePointRecordRepository;

    @Value("${file.rootPath}")
    private String rootPath;


    @Override
    public Result findAll() {
        return ResultUtil.success(userJpaRepository.findAll());
    }

    @Override
    public Result saveBody(UserInfo userInfo) {
        userJpaRepository.save(userInfo);
        return ResultUtil.success();
    }

    @Override
    public Result bindOpenId(String userId, String openId) {
        UserInfo one = userJpaRepository.findById(Long.valueOf(userId)).orElse(null);
        if (one != null) {
            UserInfo save = getWx(openId, one);
            return ResultUtil.success(save);
        }
        return ResultUtil.error(ExceptionEnum.USER_NOT_FIND);
    }

    @Override
    public Result loginTb(LoginInfo loginInfo) {
        UserInfo one = userRepository.getUserByTbOpenid(loginInfo.getOpenid());
        if (one != null) {
            one.setImage_url(loginInfo.getImageUrl());
            one.setNickName(loginInfo.getNickName());
            return getResult(userJpaRepository.save(one));
        }
        return ResultUtil.error(ExceptionEnum.USER_NOT_FIND);
    }

    @Override
    public Result loginApp(LoginInfo loginInfo) {
        if (StringUtils.isNotBlank(loginInfo.getUnionid())) {
            UserInfo one = userRepository.getUserByUnionid(loginInfo.getUnionid());
            if (one != null) {
                String s = HttpClient.doGet("https://api.weixin.qq.com/sns/userinfo?access_token=" + loginInfo.getToken() + "&openid=" + loginInfo.getOpenid());
                AppUserInfo user = JsonUtil.parseObject(s, AppUserInfo.class);
                if (user != null && user.getNickname() != null) {
                    if (user.getHeadimgurl() != null) {
                        one.setImage_url(user.getHeadimgurl());
                    }
                    if (user.getCity() != null) {
                        one.setAddress(user.getCity());
                    }
                    one.setGender(String.valueOf(user.getSex()));
                    if (user.getNickname() != null) {
                        one.setNickName(user.getNickname());
                    }
                }
                return getResult(userJpaRepository.save(one));
            } else {
                return ResultUtil.error(ExceptionEnum.USER_NOT_FIND);
            }
        } else if (StringUtils.isNotBlank(loginInfo.getOpenid())) {
            UserInfo one = userRepository.getUserByOpen_uid(loginInfo.getOpenid());
            if (one != null) {
                String s = HttpClient.doGet("https://api.weixin.qq.com/sns/userinfo?access_token=" + loginInfo.getToken() + "&openid=" + loginInfo.getOpenid());
                AppUserInfo user = JsonUtil.parseObject(s, AppUserInfo.class);
                if (user != null && user.getNickname() != null) {
                    if (user.getHeadimgurl() != null) {
                        one.setImage_url(user.getHeadimgurl());
                    }
                    if (user.getCity() != null) {
                        one.setAddress(user.getCity());
                    }
                    one.setGender(String.valueOf(user.getSex()));
                    if (user.getNickname() != null) {
                        one.setNickName(user.getNickname());
                    }
                }
                return getResult(userJpaRepository.save(one));
            } else {
                return ResultUtil.error(ExceptionEnum.USER_NOT_FIND);
            }
        } else {
            return ResultUtil.error(ExceptionEnum.USER_NOT_FIND);
        }
    }

    @Override
    public Result bindTaoBao(LoginInfo loginInfo) {
        UserInfo userInfo = userJpaRepository.getOne(Long.valueOf(loginInfo.getUserId()));
        UserInfo one = userRepository.getUserByTbOpenid(loginInfo.getOpenid());
        if (userInfo == null) {
            return ResultUtil.error(ExceptionEnum.USER_NOT_FIND);
        }
        if (userInfo.getTb_openid() != null) {
            return ResultUtil.error(ExceptionEnum.IS_BIND_RELATION);
        }
        if (one != null) {
            return ResultUtil.error(ExceptionEnum.IS_BIND);
        }
        userInfo.setTb_openid(loginInfo.getOpenid());
        userInfo.setImage_url(loginInfo.getImageUrl());
        userInfo.setNickName(loginInfo.getNickName());
        return getResult(userJpaRepository.save(userInfo));
    }

    @Override
    public Result sendMsg(String phone, String state) {
        int code = (int) ((Math.random() * 9 + 1) * 100000);
        System.out.println("sendMsg code is " + code);
        if (state.equals("forget")) {
            UserInfo userByPhone = userRepository.getUserByPhone(phone);
            if (userByPhone == null) {
                return ResultUtil.error(ExceptionEnum.USER_NOT_FIND);
            }
        }
        if (state.equals("bind")) {
            UserInfo userByPhone = userRepository.getUserByPhone(phone);
            if (userByPhone != null) {
                return ResultUtil.error(ExceptionEnum.USER_IS_EXITS);
            }
        }
        if (state.equals("register")) {
            UserInfo userByPhone = userRepository.getUserByPhone(phone);
            if (userByPhone != null) {
                return ResultUtil.error(ExceptionEnum.USER_IS_REGISTER);
            }
        }
        if (state.equals("bindWx")) {
            UserInfo userByPhone = userRepository.getUserByPhone(phone);
            if (userByPhone != null && StringUtils.isNotEmpty(userByPhone.getOpen_uid())) {
                return ResultUtil.error(ExceptionEnum.USER_IS_BIND_FOR_ANTHER_OPENID);
            }
        }
        CommonInfo three = commonRepository.findOne(79);
        //默认使用腾讯云
        if(three==null || "1".equals(three.getValue())){
            //腾讯云短信发送
            return sendMsgTencent(phone,state,code);
        }else if("2".equals(three.getValue())){
            //阿里云短信发送
            return sendMsgAlibaba(phone,state,code);
        }else{
            return sendMsgDXB(phone,state,code);
        }
    }

    private Result sendMsgAlibaba(String phone, String state,int code){

        CommonInfo three = commonRepository.findOne(83);
        String accessKeyId = three.getValue();
        CommonInfo four = commonRepository.findOne(84);
        String accessSecret = four.getValue();
        DefaultProfile profile = DefaultProfile.getProfile("cn-hangzhou", accessKeyId, accessSecret);
        IAcsClient client = new DefaultAcsClient(profile);

        CommonRequest request = new CommonRequest();
        request.setSysMethod(MethodType.POST);
        request.setSysDomain("dysmsapi.aliyuncs.com");
        request.setSysVersion("2017-05-25");
        request.setSysAction("SendSms");
        request.putQueryParameter("RegionId", "cn-hangzhou");
        request.putQueryParameter("PhoneNumbers", phone);
        request.putQueryParameter("SignName", commonRepository.findOne(95).getValue() );
        String value;
        switch (state) {
            case "register":
                value=commonRepository.findOne(80).getValue();
                break;
            case "forget":
                value=commonRepository.findOne(81).getValue();
                break;
            case "bind":
                value=commonRepository.findOne(82).getValue();
                break;
            default:
                value=commonRepository.findOne(80).getValue();
                break;
        }
        request.putQueryParameter("TemplateCode", value);
        request.putQueryParameter("TemplateParam", "{\"code\":\""+code+"\"}");
        try {
            CommonResponse response = client.getCommonResponse(request);
            System.out.println(response.getData());
            String data = response.getData();
            JSONObject jsonObject = JSON.parseObject(data);
            if("OK".equals(jsonObject.get("Code"))){
                Msg byPhone = msgJpaRepository.findByPhone(phone);
                if (byPhone != null) {
                    byPhone.setCode(String.valueOf(code));
                    byPhone.setPhone(phone);
                    msgJpaRepository.save(byPhone);
                } else {
                    Msg msg = new Msg();
                    msg.setCode(String.valueOf(code));
                    msg.setPhone(phone);
                    msgJpaRepository.save(msg);
                }
                UserInfo userByPhone = userRepository.getUserByPhone(phone);
                if (userByPhone != null) {
                    return ResultUtil.success("login");
                } else {
                    return ResultUtil.success("register");
                }
            }else {
                return ResultUtil.error(6, jsonObject.get("Message").toString());
            }
        } catch (ClientException e) {
            e.printStackTrace();
        }
        return ResultUtil.error(ExceptionEnum.SEND_ERROR);
    }



    private Result sendMsgTencent(String phone, String state,int code){
        SmsSingleSenderResult result = null;
        try {
            CommonInfo three = commonRepository.findOne(31);
            String clientId = Config.DXAppId;
            if (three != null) {
                clientId = three.getValue();
            }
            CommonInfo four = commonRepository.findOne(32);
            String clientSecret = Config.DXAppKey;
            if (four != null) {
                clientSecret = four.getValue();
            }
            /**
             * 发送短信验证码的状态、
             *
             * 在h5登录环境中 传的状态不是以下三种状态
             */
            SmsSingleSender ssender = new SmsSingleSender(Integer.valueOf(clientId), clientSecret);
            switch (state) {
                case "register":
                    result = ssender.send(0, "86", phone, "【" + commonRepository.findOne(95).getValue() + "】验证码: " + code + "，此验证码可用于登录或注册，10分钟内有效，如非您本人操作，可忽略本条消息", "", "");
                    break;
                case "forget":
                    result = ssender.send(0, "86", phone, "【" + commonRepository.findOne(95).getValue() + "】验证码: " + code + "，您正在执行找回密码操作，10分钟内有效，如非您本人操作，可忽略本条消息", "", "");
                    break;
                case "bind":
                    result = ssender.send(0, "86", phone, "【" + commonRepository.findOne(95).getValue() + "】验证码: " + code + "，您正在执行绑定手机号操作，10分钟内有效，如非您本人操作，可忽略本条消息", "", "");
                    break;
                default:
                    result = ssender.send(0, "86", phone, "【" + commonRepository.findOne(95).getValue() + "】验证码: " + code + "，此验证码可用于登录或注册，10分钟内有效，如非您本人操作，可忽略本条消息", "", "");
                    break;
            }


            System.out.println(result);
            if (result.result == 0) {
                Msg byPhone = msgJpaRepository.findByPhone(phone);
                if (byPhone != null) {
                    byPhone.setCode(String.valueOf(code));
                    byPhone.setPhone(phone);
                    msgJpaRepository.save(byPhone);
                } else {
                    Msg msg = new Msg();
                    msg.setCode(String.valueOf(code));
                    msg.setPhone(phone);
                    msgJpaRepository.save(msg);
                }
                UserInfo userByPhone = userRepository.getUserByPhone(phone);
                if (userByPhone != null) {
                    return ResultUtil.success("login");
                } else {
                    return ResultUtil.success("register");
                }
            } else {
                return ResultUtil.error(6, result.errMsg);
            }
        } catch (HTTPException | JSONException | IOException e) {
            // HTTP 响应码错误
            e.printStackTrace();
        }
        return ResultUtil.error(ExceptionEnum.SEND_ERROR);
    }


    private Result sendMsgDXB(String phone, String state, int code) {
        CommonInfo three = commonRepository.findOne(164);
        CommonInfo four = commonRepository.findOne(165);
        CommonInfo name = commonRepository.findOne(95);
        String testUsername = three.getValue(); //在短信宝注册的用户名
        String testPassword = four.getValue(); //在短信宝注册的密码
        String value="";
        switch (state) {
            case "register":
                value = "【" + name.getValue() + "】验证码: " + code + "，此验证码可用于登录或注册，10分钟内有效，如非您本人操作，可忽略本条消息";
                break;
            case "forget":
                value = "【" + name.getValue() + "】验证码: " + code + "，您正在执行找回密码操作，10分钟内有效，如非您本人操作，可忽略本条消息";
                break;
            case "bind":
                value = "【" + name.getValue() + "】验证码: " + code + "，您正在执行绑定手机号操作，10分钟内有效，如非您本人操作，可忽略本条消息";
                break;
            default:
                value = "【" + name.getValue() + "】验证码: " + code + "，此验证码可用于登录或注册，10分钟内有效，如非您本人操作，可忽略本条消息";
                break;
        }
        StringBuilder httpArg = new StringBuilder();
        httpArg.append("u=").append(testUsername).append("&");
        httpArg.append("p=").append(Md5Utils.md5s(testPassword)).append("&");
        httpArg.append("m=").append(phone).append("&");
        httpArg.append("c=").append(Md5Utils.encodeUrlString(value, "UTF-8"));
        String result = Md5Utils.request("https://api.smsbao.com/sms", httpArg.toString());
        log.error("短信包返回值："+result);
        if ("0".equals(result)) {
            Msg byPhone = msgJpaRepository.findByPhone(phone);
            if (byPhone != null) {
                byPhone.setCode(String.valueOf(code));
                byPhone.setPhone(phone);
                msgJpaRepository.save(byPhone);
            } else {
                Msg msg = new Msg();
                msg.setCode(String.valueOf(code));
                msg.setPhone(phone);
                msgJpaRepository.save(msg);
            }
            UserInfo userByPhone = userRepository.getUserByPhone(phone);
            if (userByPhone != null) {
                return ResultUtil.success("login");
            } else {
                return ResultUtil.success("register");
            }
        } else {
//            return ResultUtil.error(6, result.errMsg);
            if("30".equals(result)){
                return ResultUtil.error( 6, "错误密码");
            }else if("40".equals(result)){
                return ResultUtil.error( 6, "账号不存在");
            }else if("41".equals(result)){
                return ResultUtil.error( 6, "余额不足");
            }else if("43".equals(result)){
                return ResultUtil.error( 6, "IP地址限制");
            }else if("50".equals(result)){
                return ResultUtil.error(6,  "内容含有敏感词");
            }else if("51".equals(result)){
                return ResultUtil.error( 6, "手机号码不正确");
            }
        }

        return ResultUtil.error(6, "验证码发送失败");
    }




    @Override
    public Result getUsersByInvitation(String invitation, Pageable pageable) {
        return ResultUtil.success(userRepository.getUsersByInvitation(invitation, pageable));
    }

    @Override
    public Result getInvitation(String invitation) {
        return ResultUtil.success(userRepository.getInvitation(invitation));
    }

    @Override
    public Result getCount(String invitation) {
        return ResultUtil.success(userRepository.getCount(invitation));
    }

    @Override
    public Result getCash(String invitation) {
        List<UserInfo> invitation1 = userRepository.getInvitation(invitation);
        for (UserInfo userInfo : invitation1) {
            synchronized (SingleByUserId.getById(userInfo.getRelationId())) {
                userInfo.setBalance(1);
                userJpaRepository.save(userInfo);
            }
        }
        UserInfo userByRelationId = userRepository.getUserByRelationId(invitation);
        String value = String.valueOf(invitation1.size());
        BigDecimal a = new BigDecimal(value).multiply(new BigDecimal(userByRelationId.getJifen()));
        userByRelationId.setJifen(a.toString());
        return ResultUtil.success(userJpaRepository.save(userByRelationId));
    }

    //非线程安全实现，需要修改
    static class SingleByUserId {
        static Map<String, Object> map = new HashMap<>();

        static Object getById(String userId) {
            if (map.get(userId) != null) {
                return map.get(userId);
            } else {
                Object object = new Object();
                map.put(userId, object);
                return object;
            }
        }
    }

    @Override
    public Result bindOpenid(LoginInfo loginInfo) {
        CommonInfo one = commonRepository.findOne(4);
        Msg byPhoneAndCode = msgJpaRepository.findByPhoneAndCode(loginInfo.getPhone(), loginInfo.getMsg());
        if (byPhoneAndCode == null) {
            return ResultUtil.error(ExceptionEnum.CODE_ERROR);
        }
        UserInfo userByPhone=null;
        if(StringUtils.isNotEmpty(loginInfo.getPhone())){
            userByPhone=userRepository.getUserByPhone(loginInfo.getPhone());
        }
        if(userByPhone!=null && StringUtils.isNotEmpty(loginInfo.getOpenid())){
            UserInfo userByWxId = userRepository.getUserByWxId(loginInfo.getOpenid());
            if(userByWxId!=null){
                userJpaRepository.deleteById(userByWxId.getId());
            }
            userByPhone.setOpenId(loginInfo.getOpenid());
            return getResult(userByPhone);
        }else{
            return saveInfo(loginInfo.getPhone(), loginInfo.getOpenid(), byPhoneAndCode, loginInfo.getInvitation(), loginInfo.getPwd(), loginInfo.getPlatform());
        }
    }

    private LoginInfo isInvitaionCode(CommonInfo one,LoginInfo loginInfo){
        if (!one.getValue().equals("0")) {
            int length = loginInfo.getInvitation().length();
            UserInfo userByRelationId;
            if(length==6){
                userByRelationId = userRepository.getUserByRelationId(loginInfo.getInvitation());
                if(userByRelationId==null){
                    userByRelationId = userRepository.getUserByInvitationCode(loginInfo.getInvitation());
                }
            }else{
                userByRelationId = userRepository.getUserByInvitationCode(loginInfo.getInvitation());
                if(userByRelationId==null){
                    userByRelationId = userRepository.getUserByRelationId(loginInfo.getInvitation());
                }
            }
            if (userByRelationId == null) {
//                return null;
                loginInfo.setInvitation(commonRepository.findOne(4).getValue());
            }else{
                loginInfo.setInvitation(userByRelationId.getRelationId());
            }

        }
        return loginInfo;
    }



    //保存用户信息
    private Result saveInfo(String phone, String openid, Msg byPhoneAndCode, String invitation, String pwd, String platform) {
        CommonInfo one = commonRepository.findOne(4);
        String strDateFormat = "yyyy-MM-dd HH:mm:ss";
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(strDateFormat);
        String time = simpleDateFormat.format(new Date());
        UserInfo userInfo1 = new UserInfo();
        userInfo1.setPhone(phone);
        userInfo1.setNickName(phone);
        userInfo1.setGrade(commonRepository.findOne(40).getValue());
        UserInfo save;
        if (StringUtils.isNotBlank(invitation)) {
            if(invitation.length()==6){
                UserInfo userByInvitationCode = userRepository.getUserByInvitationCode(invitation);
                if(userByInvitationCode==null){
                    userInfo1.setInvitation(one.getValue());
                }else{
                    userInfo1.setInvitation(userByInvitationCode.getRelationId());
                }
                
            }else{
                userInfo1.setInvitation(one.getValue());
            }
            userInfo1.setIsInvitation(1);
            userInfo1.setJifen("0.00");
            userInfo1.setOrderJifen("0.00");
            userInfo1.setPwd(MD5Util.encoderByMd5(pwd));
            userInfo1.setPlatform(platform);
            userInfo1.setZhifubao(phone);
            userInfo1.setCreateAt(time);
            userInfo1.setState("true");
            //注册给定随机邀请码
            int relationId = (int) ((Math.random() * 6 + 1) * 100000);
            userInfo1.setRelationId(String.valueOf(relationId));
            save = getWx(openid, userInfo1);
            checkRelationInvitation(invitation, openid, phone);
        } else {
            userInfo1.setInvitation(one.getValue());
            userInfo1.setIsInvitation(1);
            userInfo1.setJifen("0.00");
            userInfo1.setOrderJifen("0.00");
            userInfo1.setPwd(MD5Util.encoderByMd5(pwd));
            userInfo1.setPlatform(platform);
            userInfo1.setZhifubao(phone);
            userInfo1.setCreateAt(time);
            userInfo1.setState("true");
            //注册给定随机邀请码
            int relationId = (int) ((Math.random() * 6 + 1) * 100000);
            userInfo1.setRelationId(String.valueOf(relationId));
            save = getWx(openid, userInfo1);
        }
        msgJpaRepository.deleteById(byPhoneAndCode.getId());
        return getResult(save);
    }

    /**
     * 获取微信详情
     *
     * @param openid
     * @param userInfo
     * @return
     */
    private UserInfo getWx(String openid, UserInfo userInfo) {
        User wx = accountService.getUserInfo(openid);
        if (wx.getHeadimgurl() != null) {
            userInfo.setImage_url(wx.getHeadimgurl());
        }
        if (wx.getSex() != null) {
            userInfo.setGender(String.valueOf(wx.getSex()));
        }
        if (wx.getCity() != null) {
            userInfo.setAddress(wx.getCity());
        }
        if (wx.getNickname() != null) {
            userInfo.setNickName(wx.getNickname());
        }
        if (wx.getNickname() != null) {
            userInfo.setNickName(wx.getNickname());
        }
        userInfo.setOpenId(openid);
        return userJpaRepository.saveAndFlush(userInfo);
    }

    @Override
    public Result loginTaoBao(LoginInfo loginInfo) {
        CommonInfo one = commonRepository.findOne(4);
        Msg msg1 = msgJpaRepository.findByPhoneAndCode(loginInfo.getPhone(), loginInfo.getMsg());
        //校验短信验证码
        if (msg1 == null) {
            return ResultUtil.error(ExceptionEnum.CODE_ERROR);
        }
        //校验手机号是否存在
        UserInfo userInfo = userRepository.getUserByPhone(loginInfo.getPhone());
        if (userInfo != null) {
            if (userInfo.getTb_openid() != null) {
                return ResultUtil.error(ExceptionEnum.BIND_ERROR);
            } else {
                userInfo.setTb_openid(loginInfo.getOpenid());
                userInfo.setImage_url(loginInfo.getImageUrl());
                userInfo.setNickName(loginInfo.getNickName());
                UserInfo save = userJpaRepository.save(userInfo);
                msgJpaRepository.deleteById(msg1.getId());
                return getResult(save);
            }
        } else {
            loginInfo = isInvitaionCode(one, loginInfo);
            if(loginInfo==null){
                return ResultUtil.error(ExceptionEnum.CODE_NOT_FOUND);
            }
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String time = simpleDateFormat.format(new Date());
            UserInfo userInfo1 = new UserInfo();
            userInfo1.setPhone(loginInfo.getPhone());
            userInfo1.setNickName(loginInfo.getPhone());
            UserInfo save;
            if (loginInfo.getInvitation() != null) {
                if(loginInfo.getInvitation().length()==6){
                    UserInfo userByInvitationCode = userRepository.getUserByInvitationCode(loginInfo.getInvitation());
                    userInfo1.setInvitation(userByInvitationCode.getRelationId());
                }else{
                    userInfo1.setInvitation(loginInfo.getInvitation());
                }
                userInfo1.setPwd(MD5Util.encoderByMd5(loginInfo.getPwd()));
                userInfo1.setIsInvitation(1);
                userInfo1.setJifen("0.00");
                userInfo1.setPlatform(loginInfo.getPlatform());
                userInfo1.setOrderJifen("0.00");
                userInfo1.setTb_openid(loginInfo.getOpenid());
                userInfo1.setGrade(commonRepository.findOne(40).getValue());
                userInfo1.setZhifubao(loginInfo.getPhone());
                userInfo1.setCreateAt(time);
                userInfo1.setImage_url(loginInfo.getImageUrl());
                userInfo1.setNickName(loginInfo.getNickName());
                userInfo1.setState("true");
                save = userJpaRepository.saveAndFlush(userInfo1);
                checkRelationInvitation(loginInfo.getInvitation(), loginInfo.getOpenid(), loginInfo.getPhone());
            } else {
                if(one.getValue().length()==6){
                    UserInfo userByInvitationCode = userRepository.getUserByInvitationCode(one.getValue());
                    userInfo1.setInvitation(userByInvitationCode.getRelationId());
                }else{
                    userInfo1.setInvitation(one.getValue() != null ? one.getValue() : Config.publicRelation);
                }
                userInfo1.setPwd(MD5Util.encoderByMd5(loginInfo.getPwd()));
                userInfo1.setIsInvitation(1);
                userInfo1.setJifen("0.00");
                userInfo1.setPlatform(loginInfo.getPlatform());
                userInfo1.setOrderJifen("0.00");
                userInfo1.setTb_openid(loginInfo.getOpenid());
                userInfo1.setGrade(commonRepository.findOne(40).getValue());
                userInfo1.setZhifubao(loginInfo.getPhone());
                userInfo1.setCreateAt(time);
                userInfo1.setImage_url(loginInfo.getImageUrl());
                userInfo1.setNickName(loginInfo.getNickName());
                userInfo1.setState("true");
                save=userJpaRepository.saveAndFlush(userInfo1);
            }
            msgJpaRepository.deleteById(msg1.getId());
            return getResult(save);
        }
    }

    @Override
    public Result loginWeiXinApp(LoginInfo loginInfo) {
        CommonInfo one = commonRepository.findOne(4);
        Msg msg1 = msgJpaRepository.findByPhoneAndCode(loginInfo.getPhone(), loginInfo.getMsg());
        //校验短信验证码
        if (msg1 == null) {
            return ResultUtil.error(ExceptionEnum.CODE_ERROR);
        }
        //校验手机号是否存在
        UserInfo userInfo = userRepository.getUserByPhone(loginInfo.getPhone());
        if (userInfo != null) {
            if (StringUtils.isNotBlank(userInfo.getOpen_uid())) {
                return ResultUtil.error(ExceptionEnum.BIND_ERROR);
            } else {
                String s = HttpClient.doGet("https://api.weixin.qq.com/sns/userinfo?access_token=" + loginInfo.getToken() + "&openid=" + loginInfo.getOpenid());
                AppUserInfo user = JsonUtil.parseObject(s, AppUserInfo.class);
                if (user != null && user.getNickname() != null) {
                    if (user.getHeadimgurl() != null) {
                        userInfo.setImage_url(user.getHeadimgurl());
                    }
                    if (user.getCity() != null) {
                        userInfo.setAddress(user.getCity());
                    }
                    userInfo.setGender(String.valueOf(user.getSex()));
                    if (user.getNickname() != null) {
                        userInfo.setNickName(user.getNickname());
                    }
                }
                userInfo.setOpen_uid(loginInfo.getOpenid());
                userInfo.setUnionid(loginInfo.getUnionid());
                UserInfo save = userJpaRepository.save(userInfo);
                msgJpaRepository.deleteById(msg1.getId());
                return getResult(save);
            }
        } else {
            loginInfo = isInvitaionCode(one, loginInfo);
            if(loginInfo==null){
                return ResultUtil.error(ExceptionEnum.CODE_NOT_FOUND);
            }
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String time = simpleDateFormat.format(new Date());
            UserInfo userInfo1 = new UserInfo();
            userInfo1.setPhone(loginInfo.getPhone());
            userInfo1.setNickName(loginInfo.getPhone());
            if (loginInfo.getInvitation() != null) {
                if(loginInfo.getInvitation().length()==6){
                    UserInfo userByInvitationCode = userRepository.getUserByRelationId(loginInfo.getInvitation());
                    userInfo1.setInvitation(userByInvitationCode.getRelationId());
                }else{
                    userInfo1.setInvitation(loginInfo.getInvitation());
                }
            } else {
                if(one.getValue().length()==6){
                    UserInfo userByInvitationCode = userRepository.getUserByRelationId(one.getValue());
                    userInfo1.setInvitation(userByInvitationCode.getRelationId());
                }else{
                    userInfo1.setInvitation(one.getValue() != null ? one.getValue() : Config.publicRelation);
                }
            }
            userInfo1.setPwd(MD5Util.encoderByMd5(loginInfo.getPwd()));
            userInfo1.setIsInvitation(1);
            userInfo1.setJifen("0.00");
            userInfo1.setPlatform(loginInfo.getPlatform());
            userInfo1.setOrderJifen("0.00");
            userInfo1.setUnionid(loginInfo.getUnionid());
            userInfo1.setOpen_uid(loginInfo.getOpenid());
            userInfo1.setGrade(commonRepository.findOne(40).getValue());
            userInfo1.setZhifubao(loginInfo.getPhone());
            userInfo1.setCreateAt(time);
            //注册给定随机邀请码
            int relationId = (int) ((Math.random() * 6 + 1) * 100000);
            userInfo1.setRelationId(String.valueOf(relationId));
            String s = HttpClient.doGet("https://api.weixin.qq.com/sns/userinfo?access_token=" + loginInfo.getToken() + "&openid=" + loginInfo.getOpenid());
            AppUserInfo user = JsonUtil.parseObject(s, AppUserInfo.class);
            if (user != null && user.getNickname() != null) {
                if (user.getHeadimgurl() != null) {
                    userInfo1.setImage_url(user.getHeadimgurl());
                }
                if (user.getCity() != null) {
                    userInfo1.setAddress(user.getCity());
                }
                userInfo1.setGender(String.valueOf(user.getSex()));
                if (user.getNickname() != null) {
                    userInfo1.setNickName(user.getNickname());
                }
            }
            userInfo1.setState("true");
            UserInfo save = userJpaRepository.save(userInfo1);
            if (loginInfo.getInvitation() != null) {
                checkRelationInvitation(loginInfo.getInvitation(), loginInfo.getOpenid(), loginInfo.getPhone());
            }
            msgJpaRepository.deleteById(msg1.getId());
            return getResult(save);
        }
    }


    @Override
    public Result loginCode(LoginInfo loginInfo) {

        if("17675412668".equals(loginInfo.getPhone()) && "254786".equals(loginInfo.getMsg())) {
            return getResult(userRepository.getUserByPhone(loginInfo.getPhone()));
        }

        CommonInfo one = commonRepository.findOne(4);
        Msg msg1 = msgJpaRepository.findByPhoneAndCode(loginInfo.getPhone(), loginInfo.getMsg());
        //校验短信验证码
        if (msg1 == null) {
            return ResultUtil.error(ExceptionEnum.CODE_ERROR);
        }
        //校验手机号是否存在
        UserInfo userInfo = userRepository.getUserByPhone(loginInfo.getPhone());
        if (userInfo != null) {
            if (!userInfo.getState().equals("true")) {
                return ResultUtil.error(ExceptionEnum.LIMIT_USER);
            }
            msgJpaRepository.deleteById(msg1.getId());
            return getResult(userInfo);
        } else {
            loginInfo = isInvitaionCode(one, loginInfo);
            if(loginInfo==null){
                return ResultUtil.error(ExceptionEnum.CODE_NOT_FOUND);
            }
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String time = simpleDateFormat.format(new Date());
            UserInfo userInfo1 = new UserInfo();
            userInfo1.setPhone(loginInfo.getPhone());
            userInfo1.setNickName(loginInfo.getPhone());
            if (!StringUtils.isEmpty(loginInfo.getInvitation())) {
                if(loginInfo.getInvitation().length()==6){
                    UserInfo userByInvitationCode = userRepository.getUserByRelationId(loginInfo.getInvitation());
                    userInfo1.setInvitation(userByInvitationCode.getRelationId());
                }else{
                    userInfo1.setInvitation(loginInfo.getInvitation());
                }
            } else {
                if(one.getValue().length()==6){
                    UserInfo userByInvitationCode = userRepository.getUserByInvitationCode(one.getValue());
                    userInfo1.setInvitation(userByInvitationCode.getRelationId());
                }else{
                    userInfo1.setInvitation(one.getValue() != null ? one.getValue() : Config.publicRelation);
                }
            }
            userInfo1.setPwd(MD5Util.encoderByMd5(loginInfo.getPwd()));
            userInfo1.setIsInvitation(1);
            userInfo1.setJifen("0.00");
            userInfo1.setPlatform(loginInfo.getPlatform());
            userInfo1.setOrderJifen("0.00");
            userInfo1.setGrade(commonRepository.findOne(40).getValue());
            userInfo1.setZhifubao(loginInfo.getPhone());
            userInfo1.setCreateAt(time);
            userInfo1.setState("true");
            //邀请码
            UserInfo save = userJpaRepository.saveAndFlush(userInfo1);
            setRelation(save);
            if (!StringUtils.isEmpty(loginInfo.getInvitation())) {
                checkRelationInvitation(loginInfo.getInvitation(), loginInfo.getOpenid(), loginInfo.getPhone());
            }
            msgJpaRepository.deleteById(msg1.getId());
            return getResult(save);
        }
    }


    @Override
    public Result bindPhone(String userId, String phone, String code) {
        UserInfo one = userJpaRepository.getOne(Long.valueOf(userId));
        if (one == null) {
            return ResultUtil.error(ExceptionEnum.USER_NOT_FIND);
        }
        UserInfo userInfo = userRepository.getUserByPhone(phone);
        if (userInfo != null && userInfo.getOpenId() != null) {
            return ResultUtil.error(ExceptionEnum.USER_IS_BIND_FOR_ANTHER_OPENID);
        }
        Msg byPhoneAndCode = msgJpaRepository.findByPhoneAndCode(phone, code);
        if (byPhoneAndCode == null) {
            return ResultUtil.error(ExceptionEnum.CODE_ERROR);
        }
        //小程序注册，生成随机邀请码成为会员
        if (StringUtils.isEmpty(one.getRelationId())){
            int relationId = (int)((Math.random()*9+1)*100000);
            one.setRelationId(String.valueOf(relationId));
        }
        one.setPhone(phone);
        one.setZhifubao(phone);
        return ResultUtil.success(userJpaRepository.save(one));
    }


    @Override
    public Result updatePhone(String phone, String msg, String userId) {
        Msg msg1 = msgJpaRepository.findByPhoneAndCode(phone, msg);
        //校验短信验证码
        if (msg1 != null) {
            UserInfo userInfo = userRepository.getUserByPhone(phone);
            if (userInfo != null) {
                return ResultUtil.error(ExceptionEnum.BIND_ERROR);
            } else {
                UserInfo one = userJpaRepository.getOne(Long.valueOf(userId));
                one.setPhone(phone);
                return ResultUtil.success(userJpaRepository.save(one));
            }
        }
        return ResultUtil.error(ExceptionEnum.CODE_ERROR);
    }


    @Override
    public Result bindRelationId(String userId, String relationId) {
        try {
            UserInfo userByRelationId ;
            if(relationId.length()==6){
                userByRelationId = userRepository.getUserByInvitationCode(relationId);
            }else{
                userByRelationId = userRepository.getUserByRelationId(relationId);
            }
            if (userByRelationId != null) {
                return ResultUtil.error(ExceptionEnum.RELATIONID_IS_REGISTER);
            }
            UserInfo one = userJpaRepository.findById(Long.valueOf(userId)).orElse(null);
            if (one != null) {
                one.setIsRelation(1);
                one.setRelationId(relationId);
                UserInfo save = userJpaRepository.save(one);
                if (one.getOpenId() != null) {
                    bindRelationSucces(one.getOpenId(), one.getNickName(), relationId);
                }
                return ResultUtil.success(save);
            }
            return ResultUtil.error(ExceptionEnum.USER_NOT_FIND);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ResultUtil.error(ExceptionEnum.USER_NOT_FIND);
    }

    /**
     * 加入会员通知
     */
    private void bindRelationSucces(String openId, String name, String number) {
        try{
            UserInfo userByWxId = userRepository.getUserByWxId(openId);
            //后台服务域名配置
            CommonInfo url = commonRepository.findOne(19);
            //获取全局名称
            CommonInfo four = commonRepository.findOne(12);
            MessageInfo messageInfo = new MessageInfo();
            messageInfo.setState(String.valueOf(5));
            messageInfo.setContent(name + " 恭喜你！成为" + four.getValue() + "会员！会员号【" + number + "】!您已拥有会员多项特权，点击查看详情进入会员中心，生成专属链接邀请好友可提升佣金哦");
            messageInfo.setTitle("成为会员提醒");
            messageInfo.setUserName(userByWxId.getNickName());
            messageInfo.setUserId(String.valueOf(userByWxId.getId()));
            iMessageService.saveBody(messageInfo);
            if (userByWxId.getClientid() != null) {
                pushToSingle("成为会员提醒", name + " 恭喜你！成为" + four.getValue() + "会员！会员号【" + number + "】!您已拥有会员多项特权，点击查看详情进入会员中心，生成专属链接邀请好友可提升佣金哦", userByWxId.getClientid());
            }
            CommonInfo three = commonRepository.findOne(36);
            String apkey = Config.RelationNotification;
            if (three != null) {
                apkey = three.getValue();
            }

            SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            LinkedHashMap<String, TemplateMessageItem> data = new LinkedHashMap<>();
            data.put("first", new TemplateMessageItem(name + " 恭喜你！成为" + four.getValue() + "会员", "#d71345"));
            data.put("keyword1", new TemplateMessageItem(number, "#d71345"));
            data.put("keyword2", new TemplateMessageItem(sdf1.format(new Date()), "#d71345"));
            data.put("remark", new TemplateMessageItem("您已拥有会员多项特权，点击查看详情进入会员中心，生成海报邀请好友可提升佣金哦", null));
            accountService.sendWxMessage(apkey, data, openId, url.getValue() + "/pages/member/user");

        }catch (Exception e){
            e.printStackTrace();
        }
       }

    @Override
    public Result bindRelationIdCode(String userId, String relationId, String code) {
        UserInfo one = userJpaRepository.findById(Long.valueOf(userId)).orElse(null);
        if (one != null) {
            one.setRelationId(relationId);
            one.setInvitation(code);
            UserInfo save = userJpaRepository.save(one);
            return ResultUtil.success(save);
        }
        return ResultUtil.error(ExceptionEnum.USER_NOT_FIND);
    }


    @Override
    public Result findOne(long id) {
        UserInfo userInfo = userJpaRepository.findById(id).orElse(null);
        if (userInfo != null) {
            if (userInfo.getInvitation() == null) {
                CommonInfo one = commonRepository.findOne(4);
                if(one.getValue().length()==6){
                    UserInfo userByInvitationCode = userRepository.getUserByInvitationCode(one.getValue());
                    userInfo.setInvitation(userByInvitationCode.getRelationId());
                }else{
                    userInfo.setInvitation(one.getValue() != null ? one.getValue() : Config.publicRelation);
                }
                userJpaRepository.save(userInfo);
            }
            //生成邀请码 六位
            if(StringUtils.isEmpty(userInfo.getInvitationCode())){
                userInfo.setInvitationCode(InvitationCodeUtil.toSerialCode(userInfo.getId()));
                userJpaRepository.save(userInfo);
            }
            //用户名为手机号,添加星号处理
            if (PhoneUtil.isValidChinesePhone(userInfo.getNickName())){
                userInfo.setNickName(PhoneUtil.checkUserNameIsPhone(userInfo.getNickName()));
                userJpaRepository.save(userInfo);
            }
//            if (userInfo.getRelationId() == null) {
//                setRelation(userInfo);
//            }
            /*if (userInfo.getRelationId() != null) {
                if (userInfo.getPdd() == null) {
                    //处理拼多多商品购买授权 生成推广位
                    CommonInfo clientId = commonRepository.findOne(23);
                    CommonInfo clientSecret = commonRepository.findOne(24);
                    PopClient client = new PopHttpClient(clientId.getValue() != null ? clientId.getValue() : Config.clientId, clientSecret.getValue() != null ? clientSecret.getValue() : Config.clientSecret);
                    PddDdkGoodsPidGenerateRequest request = new PddDdkGoodsPidGenerateRequest();
                    request.setNumber(1L);
                    List<String> pIdNameList = new ArrayList<String>();
                    pIdNameList.add(userInfo.getRelationId());
                    request.setPIdNameList(pIdNameList);
                    PddDdkGoodsPidGenerateResponse pddDdkGoodsPidGenerateResponse = null;
                    try {
                        pddDdkGoodsPidGenerateResponse = client.syncInvoke(request);
                        String pId = pddDdkGoodsPidGenerateResponse.getPIdGenerateResponse().getPIdList().get(0).getPId();
                        Thread.sleep(1000);
                        userInfo.setPdd(pId);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                if (userInfo.getJd() == null) {
                    *//**
             * type 站点类型 1网站推广位2.APP推广位3.社交媒体推广位4.聊天工具推广位5.二维码推广
             * unionType 1：cps推广位 2：cpc推广位
             * siteID 站点ID，即网站ID/app ID/snsID ,当type传入4以外的值时，siteId为必填
             *
             * @param name
             * @return
             *//*
                    CommonInfo one = commonRepository.findOne(28);
                    String appid = Config.JD_APPID;
                    if (one != null) {
                        appid = one.getValue();
                    }
                    CommonInfo two = commonRepository.findOne(29);
                    String keyid = Config.KEYID;
                    if (one != null) {
                        keyid = two.getValue();
                    }
                    CommonInfo three = commonRepository.findOne(30);
                    String apkey = Config.MIAOYOUQUN_Key;
                    if (three != null) {
                        apkey = three.getValue();
                    }
                    String s = HttpClient.doGet(Config.MIAOYOUQUN_URL + "/jingdong/createUnionPosition?apkey=" + apkey + "&key_id=" + keyid + "&spaceNameList=" + userInfo.getRelationId() + "&unionType=1&type=1&siteId=" + appid);
                    if (JSON.parseObject(s).getString("code").equals("200")) {
                        JSONObject orderResponse = JSON.parseObject(s).getJSONObject("data").getJSONObject("resultList");
                        String string = orderResponse.getString(userInfo.getRelationId());
                        userInfo.setJd(string);
                    } else {
                        logger.error(s);
                    }
                }
                UserInfo save = userJpaRepository.save(userInfo);
                return ResultUtil.success(save);
            }*/
        }

        return ResultUtil.success(userInfo);
    }

    private void setRelation(UserInfo userInfo) {
        int t = (int) ((Math.random() * 9 + 1) * 100000);
        UserInfo relationId = userRepository.getUserByRelationId(String.valueOf(t));
        if (relationId == null) {
            userInfo.setRelationId(String.valueOf(t));
            userJpaRepository.save(userInfo);
        } else {
            setRelation(userInfo);
        }
    }

    @Override
    public Result delete(long id) {
        userJpaRepository.deleteById(id);
        return ResultUtil.success();
    }


    @Override
    public Result find(String phone, Pageable pageable) {
        return ResultUtil.success(userRepository.find(phone, pageable));
    }

    @Override
    public Result findList(Pageable pageable) {
        return ResultUtil.success(userJpaRepository.findAll(pageable));
    }

    @Override
    @Transactional
    public Result updateBody(UserInfo userInfo) {
        UserInfo foodBanner1 = userJpaRepository.findById(userInfo.getId()).orElse(null);
        assert foodBanner1 != null;
        BeanUtils.copyProperties(userInfo, foodBanner1);
        return ResultUtil.success();
    }

    @Override
    public Result loginByOpenId(String openid, String relation) {
        if (!StringUtils.isEmpty(openid)) {
            CommonInfo one = commonRepository.findOne(4);
            User wx = accountService.getUserInfo(openid);
            if (wx != null && wx.getUnionid() != null) {
                UserInfo userByUnionid = userRepository.getUserByUnionid(wx.getUnionid());
                if (userByUnionid != null) {
                    if (wx.getHeadimgurl() != null) {
                        userByUnionid.setImage_url(wx.getHeadimgurl());
                    }
                    if (wx.getSex() != null) {
                        userByUnionid.setGender(String.valueOf(wx.getSex()));
                    }
                    if (wx.getCity() != null) {
                        userByUnionid.setAddress(wx.getCity());
                    }
                    if (wx.getNickname() != null) {
                        userByUnionid.setNickName(wx.getNickname());
                    }
                    userByUnionid.setOpenId(openid);
                    UserInfo save = userJpaRepository.save(userByUnionid);
                    return getResult(save);
                } else {
                    return wxLoginByOpenid(openid, relation, one);
                }
            } else {
                return wxLoginByOpenid(openid, relation, one);
            }

        } else {
            return ResultUtil.error(ExceptionEnum.LIMIT_USER);
        }

    }

    private Result wxLoginByOpenid(String openid, String relation, CommonInfo one) {
        UserInfo userByWxId = userRepository.getUserByWxId(openid);
        User wx = accountService.getUserInfo(openid);
        if (userByWxId == null) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String time = simpleDateFormat.format(new Date());
            UserInfo userInfo = new UserInfo();
            userInfo.setPwd(MD5Util.encoderByMd5("123456"));
            userInfo.setJifen("0.00");
            userInfo.setGrade(commonRepository.findOne(40).getValue());
            userInfo.setOrderJifen("0.00");
            if (relation != null) {
                if(relation.length()==6){
                    UserInfo userByInvitationCode = userRepository.getUserByInvitationCode(relation);
                    userInfo.setInvitation(userByInvitationCode.getRelationId());
                }else{
                    userInfo.setInvitation(relation);
                }
            } else {
                if(one.getValue().length()==6){
                    UserInfo userByInvitationCode = userRepository.getUserByInvitationCode(one.getValue());
                    userInfo.setInvitation(userByInvitationCode.getRelationId());
                }else{
                    userInfo.setInvitation(one.getValue() != null ? one.getValue() : Config.publicRelation);
                }
            }
            userInfo.setIsInvitation(1);
            userInfo.setCreateAt(time);
            userInfo.setPlatform("weixin");
            userInfo.setState("true");
            if (wx.getHeadimgurl() != null) {
                userInfo.setImage_url(wx.getHeadimgurl());
            }
            if (wx.getSex() != null) {
                userInfo.setGender(String.valueOf(wx.getSex()));
            }
            if (wx.getCity() != null) {
                userInfo.setAddress(wx.getCity());
            }
            if (wx.getNickname() != null) {
                userInfo.setNickName(wx.getNickname());
            }
            if (wx.getUnionid() != null) {
                userInfo.setUnionid(wx.getUnionid());
            }
            userInfo.setOpenId(openid);
            UserInfo save = userJpaRepository.saveAndFlush(userInfo);
            if (relation != null) {
                checkRelationInvitation(relation, openid, null);
            }
            return getResult(save);
        }
        if (!userByWxId.getState().equals("true")) {
            return ResultUtil.error(ExceptionEnum.LIMIT_USER);
        }
        UserInfo save = getWx(openid, userByWxId);
        return getResult(save);
    }

    @Override
    public Result loginByMpId(String openids) {
        CommonInfo one = commonRepository.findOne(4);
        UserInfo userByMpId = userRepository.getUserByMpId(openids);
        if (userByMpId == null) {
            User wx = accountService.getUserInfo(openids);
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String time = simpleDateFormat.format(new Date());
            UserInfo userInfo = new UserInfo();
            userInfo.setPwd(MD5Util.encoderByMd5("123456"));
            userInfo.setJifen("0.00");
            userInfo.setGrade(commonRepository.findOne(40).getValue());
            userInfo.setOrderJifen("0.00");
            if(one.getValue().length()==6){
                UserInfo userByInvitationCode = userRepository.getUserByInvitationCode(one.getValue());
                userInfo.setInvitation(userByInvitationCode.getRelationId());
            }else{
                userInfo.setInvitation(one.getValue() != null ? one.getValue() : Config.publicRelation);
            }
            userInfo.setIsInvitation(1);
            userInfo.setCreateAt(time);
            userInfo.setPlatform("mp");
            userInfo.setState("true");
            userInfo.setMpId(openids);
            UserInfo save = userJpaRepository.save(userInfo);
            return getResult(save);
        }
        if (!userByMpId.getState().equals("true")) {
            return ResultUtil.error(ExceptionEnum.LIMIT_USER);
        }
        return getResult(userByMpId);
    }


    /**
     * 微信公众号注册/更新用户
     * @param openid
     * @param relation
     * @return
     */
    @Override
    public Result loginByOpenIdWithRelation(String openid, String relation,String unionid) {
        logger.error("loginByOpenIdWithRelation----" + openid);
        CommonInfo one = commonRepository.findOne(4);
        UserInfo userByWxId = new UserInfo();
        if (StringUtils.isNotEmpty(unionid)){
            userByWxId = userRepository.getUserByUnionid(unionid);
        }else if(StringUtils.isNotEmpty(openid)) {
            userByWxId = userRepository.getUserByWxId(unionid);
        }
        if (userByWxId == null) {
            logger.error("userByWxId is null----" + relation);
            User wx = accountService.getUserInfo(openid);
            if (wx.getNickname() != null) {
                logger.error("getUserInfo ----" + wx.getNickname());
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String time = simpleDateFormat.format(new Date());
                UserInfo userInfo = new UserInfo();
                userInfo.setGrade(commonRepository.findOne(40).getValue());
                if (relation == null) {
                    if(one.getValue().length()==6){
                        UserInfo userByInvitationCode = userRepository.getUserByInvitationCode(one.getValue());
                        userInfo.setInvitation(userByInvitationCode.getRelationId());
                    }else{
                        userInfo.setInvitation(one.getValue() != null ? one.getValue() : Config.publicRelation);
                    }

                } else {
                    if(relation.length()==6){
                        UserInfo userByInvitationCode = userRepository.getUserByRelationId(relation);
                        userInfo.setInvitation(userByInvitationCode.getRelationId());
                    }else{
                        userInfo.setInvitation(relation);
                    }
                }
                if (wx.getHeadimgurl() != null) {
                    userInfo.setImage_url(wx.getHeadimgurl());
                }
                if (wx.getSex() != null) {
                    userInfo.setGender(String.valueOf(wx.getSex()));
                }
                if (wx.getCity() != null) {
                    userInfo.setAddress(wx.getCity());
                }
                if (wx.getNickname() != null) {
                    userInfo.setNickName(wx.getNickname());
                }
                userInfo.setPwd(MD5Util.encoderByMd5("123456"));
                userInfo.setJifen("0.00");
                userInfo.setOrderJifen("0.00");
                userInfo.setIsInvitation(1);
                userInfo.setPlatform("weixin");
                userInfo.setCreateAt(time);
                userInfo.setState("true");
                userInfo.setOpenId(openid);
                userInfo.setOpen_uid(openid);
                userInfo.setUnionid(unionid);
                UserInfo save = userJpaRepository.saveAndFlush(userInfo);
                if (relation != null) {
                    checkRelationInvitation(relation, openid, null);
                }
                return getResult(save);
            } else {
                return ResultUtil.error(ExceptionEnum.USER_NOT_FIND);
            }
        }
        if (!userByWxId.getState().equals("true")) {
            return ResultUtil.error(ExceptionEnum.LIMIT_USER);
        }
        UserInfo save = getWx(openid, userByWxId);
        return getResult(save);
    }


    private Result getResult(UserInfo userInfo) {
        Token byUserIds = tokenRepository.findByUserId(String.valueOf(userInfo.getId()));
        if (byUserIds == null) {
            String uuid = UUID.randomUUID().toString();
            Token token = new Token();
            token.setUserId(String.valueOf(userInfo.getId()));
            token.setUuid(uuid);
            Token save = tokenJpaRepository.save(token);
            return ResultUtil.success(save);
        }
        return ResultUtil.success(byUserIds);
    }

    @Override
    public Result Login(LoginInfo loginInfo) {
        try {
            UserInfo userByPhone = userRepository.getUserByPhone(loginInfo.getPhone());
            if (userByPhone == null) {
                return ResultUtil.error(ExceptionEnum.USER_NOT_FIND);
            }
            UserInfo login = userRepository.login(loginInfo.getPhone());
            if (login == null) {
                return ResultUtil.error(ExceptionEnum.USER_PWD_ERROR);
            }
            if (!login.getState().equals("true")) {
                return ResultUtil.error(ExceptionEnum.LIMIT_USER);
            }
            if (login.getPwd() == null) {
                return ResultUtil.error(ExceptionEnum.USER_PWD_ERROR);
            }
            if (!MD5Util.checkMD5(loginInfo.getPwd(), login.getPwd())) {
                return ResultUtil.error(ExceptionEnum.USER_PWD_ERROR);
            }
            return getResult(login);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(ExceptionEnum.ERROR);
        }
    }

    /**
     * 小程序注册/更新
     * @param loginInfo
     * @return
     */
    @Override
    public Result mpUpdateUser(LoginInfo loginInfo) {
        log.info("mpUpdateUser input = {}", JsonUtils.toJsonString(loginInfo));
        // 这里是查询默认的注册邀请码
        CommonInfo one = commonRepository.findOne(4);
        if (loginInfo.getOpenid() != null) {
            UserInfo userByPhone=null;
            // 输入的手机号不为空的情况
            if(StringUtils.isNotEmpty(loginInfo.getPhone())){
                // 通过手机号查询用户记录
                userByPhone = userRepository.getUserByPhone(loginInfo.getPhone());
            }
            // 通过手机号能查询到记录，更新记录
            if(userByPhone != null){
                log.info("通过手机号能查找到记录，更新原记录:{}", JsonUtils.toJsonString(userByPhone));
                UserInfo userInfo = userRepository.getUserByMpId(loginInfo.getOpenid());
                // 手机号和小程序openId都没变，为什么要删除呢？？但是先不管吧，应该也走不到这个逻辑
                if(userInfo!=null){
                    userJpaRepository.deleteById(userInfo.getId());
                }
                userByPhone.setMpId(loginInfo.getOpenid());
                userByPhone.setNickName(loginInfo.getNickName());
                // 现在授权已经获取不到头像了，在有值的情况下不更新
                if(StringUtils.isEmpty(userByPhone.getImage_url())) {
                    userByPhone.setImage_url(loginInfo.getImageUrl());
                }
                UserInfo save = userJpaRepository.save(userByPhone);
                return getResult(save);
            }else{
                /**
                 * 逻辑走到这里，有两种情况：
                 * 1. 入参没有输入手机号，用户信息已经有手机号的情况无需授权获取手机号
                 * 2. 入参有输入手机号，但是通过手机号没有查询到用户信息
                 */
                UserInfo userInfo = userRepository.getUserByMpId(loginInfo.getOpenid());
                if(userInfo!=null){
                    log.info("通过小程序openId能查询到用户记录，更新用户记录:{}", JsonUtils.toJsonString(userInfo));
                    // 现在授权已经获取不到头像了，在有值的情况下不更新
                    if(StringUtils.isEmpty(userInfo.getImage_url())) {
                        userInfo.setImage_url(loginInfo.getImageUrl());
                    }
                    if(StringUtils.isNotEmpty(loginInfo.getNickName())) {
                        userInfo.setNickName(loginInfo.getNickName());
                    }
                    userInfo.setUnionid(loginInfo.getUnionid());
                    // 手机号有输入的情况下才覆盖
                    if(StringUtils.isNotEmpty(loginInfo.getPhone())) {
                        userInfo.setPhone(loginInfo.getPhone());
                    }
                    UserInfo save = userJpaRepository.save(userInfo);
                    return getResult(save);
                }
                // 走到这里是新注册的情况
                log.info("开始执行新注册用户逻辑.");
                loginInfo = isInvitaionCode(one, loginInfo);
                if(loginInfo==null){
                    return ResultUtil.error(ExceptionEnum.CODE_NOT_FOUND);
                }
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                String time = simpleDateFormat.format(new Date());
                UserInfo userInfo1 = new UserInfo();
                userInfo1.setNickName(loginInfo.getNickName());
                if (loginInfo.getInvitation() != null) {
                    if(loginInfo.getInvitation().length()!=6){
                        UserInfo userByInvitationCode = userRepository.getUserByInvitationCode(loginInfo.getInvitation());
                        userInfo1.setInvitation(userByInvitationCode.getRelationId());
                    }else{
                        userInfo1.setInvitation(loginInfo.getInvitation());
                    }
                } else {
                    if(one.getValue().length()!=6){
                        UserInfo userByInvitationCode = userRepository.getUserByInvitationCode(one.getValue());
                        userInfo1.setInvitation(userByInvitationCode.getRelationId());
                    }else{
                        userInfo1.setInvitation(one.getValue() != null ? one.getValue() : Config.publicRelation);
                    }
                }
                userInfo1.setPhone(loginInfo.getPhone());
                userInfo1.setPwd(MD5Util.encoderByMd5("123456"));
                userInfo1.setIsInvitation(1);
                userInfo1.setJifen("0.00");
                userInfo1.setImage_url(loginInfo.getImageUrl());
                userInfo1.setPlatform("mp");
                userInfo1.setOrderJifen("0.00");
                userInfo1.setMpId(loginInfo.getOpenid());
                userInfo1.setGrade(commonRepository.findOne(40).getValue());
                userInfo1.setCreateAt(time);
                userInfo1.setState("true");
                UserInfo save = userJpaRepository.save(userInfo1);
                setRelation(save);
                if (loginInfo.getInvitation() != null) {
                    checkRelationInvitation(loginInfo.getInvitation(), loginInfo.getOpenid(), loginInfo.getPhone());
                }
                return getResult(save);
            }
        }
        return ResultUtil.error(-1, "登录失败！");
    }

    @Override
    public UserInfo getUserByPhone(String phone) {
        List<UserInfo> userInfos = userRepository.queryByPhone(phone);
        return CollectionUtils.isEmpty(userInfos) ? null : userInfos.get(0);
    }

    @Override
    public Result getUserByWxId(String wxId) {
        return ResultUtil.success(userRepository.getUserByWxId(wxId));
    }

    @Override
    public Result getUserByRelationId(String relationId) {
        return ResultUtil.success(userRepository.getUserByRelationId(relationId));
    }

    @Override
    @Transactional
    public Result updateState(String state, String id) {
        Integer adminInfo = userRepository.updateState(state, Long.parseLong(id));
        if (adminInfo == 1) {
            return ResultUtil.success();
        } else {
            return ResultUtil.error(ExceptionEnum.STATE_PWD_ERROR);
        }
    }

    @Override
    @Transactional
    public Result updatePwd(String old, String pwd, String userId) {
        UserInfo one = userJpaRepository.findById(Long.valueOf(userId)).orElse(null);
        if (one == null) {
            return ResultUtil.error(ExceptionEnum.USER_NOT_FIND);
        }
        if (!one.getPwd().equals(old)) {
            return ResultUtil.error(ExceptionEnum.OLD_PWD_ERROR);
        }
        if (one.getPwd().equals(pwd)) {
            return ResultUtil.error(ExceptionEnum.OLD_NOT_SAME_NEW_PWD_ERROR);
        }
        return ResultUtil.success(userRepository.updatePwd(pwd, userId));
    }


    @Override
    public Result forgetPwd(String pwd, String phone, String msg) {
        try {
            Msg byPhoneAndCode = msgJpaRepository.findByPhoneAndCode(phone, msg);
            //校验短信验证码
            if (byPhoneAndCode == null) {
                return ResultUtil.error(ExceptionEnum.CODE_ERROR);
            }
            UserInfo userByPhone = userRepository.getUserByPhone(phone);
            userByPhone.setPwd(MD5Util.encoderByMd5(pwd));
            msgJpaRepository.deleteById(byPhoneAndCode.getId());
            userJpaRepository.save(userByPhone);
            return ResultUtil.success();
        } catch (Exception e) {
            e.printStackTrace();
            return ResultUtil.error(ExceptionEnum.ERROR);
        }
    }

    @Override
    public Result LoginAndRegister(LoginInfo loginInfo) {
        return null;
    }

    @Override
    public Result loginAndCode(LoginInfo loginInfo) {
        return null;
    }

    @Override
    public Result checkRelationInvitations(String invitation, String userOpenid, String phone) {
        checkRelationInvitation(invitation, userOpenid, phone);
        return ResultUtil.success();
    }


    private void checkRelationInvitation(String invitation, String userOpenid, String phone) {
        UserInfo userByRelationId = userRepository.getUserByRelationId(invitation);
        if (userByRelationId != null) {
            User wx = accountService.getUserInfo(userByRelationId.getOpenId());
            if (wx != null) {
                if (userOpenid != null) {
                    User userInfo = accountService.getUserInfo(userOpenid);
                    if (userInfo != null && userInfo.getNickname() != null) {
                        invitationSuccess(wx.getOpenid(), userInfo.getNickname());
                    } else {
                        if (phone != null) {
                            invitationSuccess(wx.getOpenid(), phone);
                        } else {
                            invitationSuccess(wx.getOpenid(), userOpenid);
                        }
                    }
                } else {
                    if (phone != null) {
                        invitationSuccess(wx.getOpenid(), phone);
                    } else {
                        invitationSuccess(wx.getOpenid(), "未知");
                    }
                }
                String count = userRepository.getCount(invitation);
                String value = commonRepository.findOne(42).getValue();//邀请人数
                String max = commonRepository.findOne(41).getValue();//用户最高佣金
                String min = commonRepository.findOne(40).getValue();//用户最低佣金
                //最低到最高提升空间
                double num=Double.parseDouble(max)-Double.parseDouble(min);
                //计算每邀请一个人提升值
                double yong=num/Double.parseDouble(value);
                Double yongjin;
                int anInt = Integer.parseInt(count);//已邀请人数
                int overNumber = Integer.valueOf(value) - anInt;//剩余可邀请人数
                if(anInt>=Integer.parseInt(value)){
                    yongjin=Double.parseDouble(max);
                }else{
                    yongjin=Double.parseDouble(min) + (anInt * yong);
                }
                DecimalFormat df = new DecimalFormat("#########.##");
                userByRelationId.setGrade(df.format(Float.parseFloat(yongjin.toString())));
                userByRelationId.setIsTuan(1);

                if (overNumber > 0) {
                    userByRelationId.setGradeNumber("还可邀请" + overNumber + "人");
                    userByRelationId.setGradeDes("VIP" + anInt);
                    userByRelationId.setGradeIndex(anInt + "");
                } else {
                    userByRelationId.setGradeNumber("还可邀请0人");
                    userByRelationId.setGradeDes("超级VIP");
                    userByRelationId.setGradeIndex(value);
                }
                userJpaRepository.saveAndFlush(userByRelationId);
                if (anInt <= Integer.valueOf(value)) {
                    totalSuccess(userByRelationId.getOpenId(), anInt, overNumber);
                }
            }
        }
    }

    /**
     * 好友邀请成功提醒
     */
    private void invitationSuccess(String openId, String name) {
        try{
            UserInfo userByWxId = userRepository.getUserByWxId(openId);
            User userInfo = accountService.getUserInfo(openId);
            if (userByWxId != null && userInfo != null && userInfo.getNickname() != null) {
                MessageInfo messageInfo = new MessageInfo();
                messageInfo.setState(String.valueOf(5));
                messageInfo.setContent("你的团队有新成员加入啦！！" + name);
                messageInfo.setTitle("团队成员加入提醒");
                messageInfo.setUserName(userByWxId.getNickName());
                messageInfo.setUserId(String.valueOf(userByWxId.getId()));
                iMessageService.saveBody(messageInfo);

                CommonInfo three = commonRepository.findOne(33);
                if (userByWxId.getClientid() != null) {
                    pushToSingle("团队成员加入提醒", "你的团队有新成员加入啦！！" + name, userByWxId.getClientid());
                }
                String apkey = Config.InvitaionNotification;
                if (three != null) {
                    apkey = three.getValue();
                }

                SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                CommonInfo urls = commonRepository.findOne(19);
                LinkedHashMap<String, TemplateMessageItem> data = new LinkedHashMap<>();
                data.put("first", new TemplateMessageItem("你的团队有新成员加入啦！！", "#d71345"));
                data.put("keyword1", new TemplateMessageItem(name, "#d71345"));
                data.put("keyword2", new TemplateMessageItem(name, "#d71345"));
                data.put("keyword3", new TemplateMessageItem(sdf1.format(new Date()), "#d71345"));
                data.put("remark", new TemplateMessageItem("点击查看详情进入【我的】-【团队成员】-查看", null));
                accountService.sendWxMessage(apkey, data, openId, urls.getValue() + "/pages/member/user");
                //添加积分
                String jifen = commonRepository.findOne(107).getValue();
                userRepository.addOrderJifen(jifen, userByWxId.getId());
                //积分明细
                JiFen jiFen = new JiFen();
                jiFen.setCreateAt(DateUtil.createTime());
                jiFen.setNumber(jifen);
                jiFen.setUserId(String.valueOf(userByWxId.getId()));
                jiFen.setContent("邀请成员");
                jiFen.setDes("邀请成员获得积分:+"+jifen);
                jiFenService.saveBody(jiFen);
            }
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    /**
     * 会员升级提醒
     */
    private void totalSuccess(String openId, Integer dengji, Integer number) {
        try{
            UserInfo userByWxId = userRepository.getUserByWxId(openId);
            User userInfo = accountService.getUserInfo(openId);
            if (userByWxId != null && userInfo != null && userInfo.getNickname() != null) {
                MessageInfo messageInfo = new MessageInfo();
                CommonInfo urls = commonRepository.findOne(19);
                CommonInfo three = commonRepository.findOne(34);
                String apkey = Config.ShengjiNotification;
                if (three != null) {
                    apkey = three.getValue();
                }
                LinkedHashMap<String, TemplateMessageItem> data = new LinkedHashMap<>();
                if (number<=0) {
                    messageInfo.setContent("恭喜你已经成为超级VIP啦！！已享有超级VIP的福利，拥有最高返佣特权哦");
                    messageInfo.setTitle("会员等级提升");
                    if (userByWxId.getClientid() != null) {
                        pushToSingle("会员等级提升", "恭喜你已经成为超级VIP啦！！已享有超级VIP的福利，拥有最高返佣特权哦", userByWxId.getClientid());
                    }
                    data.put("first", new TemplateMessageItem("恭喜你已经成为超级VIP啦！！", "#d71345"));
                    data.put("keyword1", new TemplateMessageItem("超级VIP", "#d71345"));
                    data.put("keyword2", new TemplateMessageItem("已享有超级VIP的福利，拥有最高返佣特权哦", "#d71345"));
                } else {
                    messageInfo.setContent("恭喜你，你的会员等级提升啊！！再邀请【" + number + "人】到达最高等级享受最高佣金");
                    messageInfo.setTitle("会员等级提升");
                    if (userByWxId.getClientid() != null) {
                        pushToSingle("会员等级提升", "恭喜你，你的会员等级提升啊！！！！再邀请【" + number + "人】到达最高等级享受最高佣金", userByWxId.getClientid());
                    }
                    data.put("first", new TemplateMessageItem("恭喜你，你的会员等级提升啊！！", "#d71345"));
                    data.put("keyword1", new TemplateMessageItem("VIP" + dengji, "#d71345"));
                    data.put("keyword2", new TemplateMessageItem("再邀请【" + number + "人】到达最高等级享受最高佣金", "#d71345"));
                }
                messageInfo.setState(String.valueOf(5));
                messageInfo.setUserName(userByWxId.getNickName());
                messageInfo.setUserId(String.valueOf(userByWxId.getId()));
                iMessageService.saveBody(messageInfo);
                data.put("remark", new TemplateMessageItem("点击【查看详情】进入查看等级，如有疑问请在公众号中发送您的问题联系客服", null));
                accountService.sendWxMessage(apkey, data, openId, urls.getValue() + "/pages/member/user");
            }
            }catch (Exception e){
            e.printStackTrace();
        }
    }


    /**
     * 对单个用户推送消息
     * <p>
     * 场景1：某用户发生了一笔交易，银行及时下发一条推送消息给该用户。
     * <p>
     * 场景2：用户定制了某本书的预订更新，当本书有更新时，需要向该用户及时下发一条更新提醒信息。
     * 这些需要向指定某个用户推送消息的场景，即需要使用对单个用户推送消息的接口。
     */
    @Override
    public void pushToSingle(String title, String content, String clientId) {
        try{
            if(StringUtils.isNotEmpty(clientId)){
                GtApiConfiguration apiConfiguration = new GtApiConfiguration();
                //填写应用配置
                apiConfiguration.setAppId(commonRepository.findOne(61).getValue());
                apiConfiguration.setAppKey(commonRepository.findOne(60).getValue());
                apiConfiguration.setMasterSecret(commonRepository.findOne(62).getValue());
                // 接口调用前缀，请查看文档: 接口调用规范 -> 接口前缀, 可不填写appId
                apiConfiguration.setDomain("https://restapi.getui.com/v2/");
                // 实例化ApiHelper对象，用于创建接口对象
                ApiHelper apiHelper = ApiHelper.build(apiConfiguration);
                // 创建对象，建议复用。目前有PushApi、StatisticApi、UserApi
                PushApi pushApi = apiHelper.creatApi(PushApi.class);
                //根据cid进行单推
                PushDTO<Audience> pushDTO = new PushDTO<Audience>();
                // 设置推送参数
                pushDTO.setRequestId(System.currentTimeMillis() + "");
                PushMessage pushMessage = new PushMessage();
                //安卓推送
                GTNotification notification = new GTNotification();
                pushDTO.setPushMessage(pushMessage);
                // 配置通知栏图标
                notification.setLogo(commonRepository.findOne(19).getValue() + "/logo.png"); //配置通知栏图标，需要在客户端开发时嵌入，默认为push.png
                // 配置通知栏网络图标
                notification.setLogoUrl(commonRepository.findOne(19).getValue() + "/logo.png");
                notification.setTitle(title);
                notification.setBody(content);
                notification.setClickType("startapp");
                notification.setUrl(commonRepository.findOne(19).getValue());
                notification.setChannelLevel("3");
                pushMessage.setNotification(notification);
                // 设置接收人信息
                Audience audience = new Audience();
                audience.addCid(clientId);
                pushDTO.setAudience(audience);
                // 进行cid单推
                ApiResult<Map<String, Map<String, String>>> apiResult = pushApi.pushToSingleByCid(pushDTO);
                if (apiResult.isSuccess()) {
                    // success
                    log.error("安卓消息推送成功：" + apiResult.getData());
                } else {
                    // failed
                    log.error("安卓消息推送成功失败：code:" + apiResult.getCode() + ", msg: " + apiResult.getMsg());
                    pushMessage.setTransmission(title);
                    pushDTO.setPushMessage(pushMessage);
                    PushChannel pushChannel=new PushChannel();
                    IosDTO iosDTO=new IosDTO();
                    Aps aps=new Aps();
                    Alert alert=new Alert();
                    alert.setTitle(title);
                    alert.setBody(content);
                    aps.setAlert(alert);
                    aps.setSound("default");
                    iosDTO.setAps(aps);
                    pushChannel.setIos(iosDTO);
                    pushDTO.setPushChannel(pushChannel);
                    pushDTO.setAudience(audience);
                    apiResult = pushApi.pushToSingleByCid(pushDTO);
                    if (apiResult.isSuccess()) {
                        // success
                        log.error("苹果消息推送成功：" + apiResult.getData());
                    } else {
                        // failed
                        log.error("苹果消息推送成功失败：code:" + apiResult.getCode() + ", msg: " + apiResult.getMsg());
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("消息推送异常："+e.getMessage(),e);
        }
    }

    /**
     * 自营商城订单通知
     * @param userId 用户id
     * @param orderNum 订单号
     * @param payMoney 支付金额
     * @param createTime 下单时间
     */
    @Override
    public void orderPay(Long userId, String orderNum, String payMoney, String createTime) {
        UserInfo user = userRepository.getUserById(userId);
        String openId = user.getOpenId()==null?user.getOpen_uid():user.getOpenId()==null?user.getOpen_uid():user.getOpenId();
        if (user != null && user.getOpenId() != null) {
            CommonInfo urls = commonRepository.findOne(19); //域名
            String templateId = commonRepository.findOne(35).getValue(); //消息模板
            LinkedHashMap<String, TemplateMessageItem> data = new LinkedHashMap<>();
            data.put("first", new TemplateMessageItem("自营商城订单通知", "#d71345"));
            data.put("keyword1", new TemplateMessageItem(orderNum, "#d71345"));
            data.put("keyword2", new TemplateMessageItem(payMoney, "#d71345"));
            data.put("keyword3", new TemplateMessageItem(createTime, "#d71345"));
            data.put("remark", new TemplateMessageItem("点击查看详情进入【我的】-【我的订单】-查看", null));
            accountService.sendWxMessage(templateId, data, openId, urls.getValue() + "/pages/zysc/my/myList#/pages/zysc/my/myList");
        }
        //订单消息
        MessageInfo messageInfo = new MessageInfo();
        messageInfo.setState("4");
        messageInfo.setTitle("订单支付成功");
        messageInfo.setContent("订单编号："+orderNum+"，支付金额："+payMoney);
        messageInfo.setUserName(user.getNickName());
        messageInfo.setUserId(userId.toString());
        iMessageService.saveBody(messageInfo);
        if (user.getClientid() != null) {
            pushToSingle("订单支付成功", "订单编号："+orderNum+"，支付金额："+payMoney, user.getClientid());
        }
    }

    @Override
    public void orderCancel(Long userId, String orderNum, String time) {
        UserInfo user = userRepository.getUserById(userId);
        String openId = user.getOpenId()==null?user.getOpen_uid():user.getOpenId();
        if (user != null && user.getOpenId() != null) {
            CommonInfo urls = commonRepository.findOne(19); //域名
            String templateId = commonRepository.findOne(86).getValue(); //消息模板
            LinkedHashMap<String, TemplateMessageItem> data = new LinkedHashMap<>();
            data.put("first", new TemplateMessageItem("自营商城订单通知", "#d71345"));
            data.put("keyword1", new TemplateMessageItem(orderNum, "#d71345"));
            data.put("keyword2", new TemplateMessageItem(time, "#d71345"));
            data.put("remark", new TemplateMessageItem("点击查看详情进入【我的】-【我的订单】-查看", null));
            accountService.sendWxMessage(templateId, data, openId, urls.getValue() + "/pages/zysc/my/myList#/pages/zysc/my/myList");
        }
    }

    @Override
    public void orderExpress(Long userId, String orderNum, String time, String expressName, String expressNumber, String address) {
        UserInfo user = userRepository.getUserById(userId);
        String openId = user.getOpenId()==null?user.getOpen_uid():user.getOpenId();
        if (user != null && user.getOpenId() != null) {
            CommonInfo urls = commonRepository.findOne(19); //域名
            String templateId = commonRepository.findOne(87).getValue(); //消息模板
            LinkedHashMap<String, TemplateMessageItem> data = new LinkedHashMap<>();
            data.put("first", new TemplateMessageItem("自营商城订单通知", "#d71345"));
            data.put("keyword1", new TemplateMessageItem(orderNum, "#d71345"));
            data.put("keyword2", new TemplateMessageItem(time, "#d71345"));
            data.put("keyword3", new TemplateMessageItem(expressName, "#d71345"));
            data.put("keyword4", new TemplateMessageItem(expressNumber, "#d71345"));
            data.put("keyword5", new TemplateMessageItem(address, "#d71345"));
            data.put("remark", new TemplateMessageItem("点击查看详情进入【我的】-【我的订单】-查看", null));
            accountService.sendWxMessage(templateId, data, openId, urls.getValue() + "/pages/zysc/my/myList#/pages/zysc/my/myList");
        }
        //订单消息
        MessageInfo messageInfo = new MessageInfo();
        messageInfo.setState("4");
        messageInfo.setTitle("订单发货成功");
        messageInfo.setContent("订单编号："+orderNum+"，发货时间："+time+"，快递公司："+expressName+"，快递单号:"+expressNumber+"，收货地址："+address);
        messageInfo.setUserName(user.getNickName());
        messageInfo.setUserId(userId.toString());
        iMessageService.saveBody(messageInfo);
        if (user.getClientid() != null) {
            pushToSingle("订单发货成功", "订单编号："+orderNum+"，发货时间："+time+"，快递公司："+expressName+"，快递单号:"+expressNumber+"，收货地址："+address, user.getClientid());
        }
    }

    @Override
    public void orderRefund(Long userId, String payMoney) {
        UserInfo user = userRepository.getUserById(userId);
        String openId = user.getOpenId()==null?user.getOpen_uid():user.getOpenId();
        if (user != null && user.getOpenId() != null) {
            CommonInfo urls = commonRepository.findOne(19); //域名
            String templateId = commonRepository.findOne(88).getValue(); //消息模板
            LinkedHashMap<String, TemplateMessageItem> data = new LinkedHashMap<>();
            data.put("first", new TemplateMessageItem("自营商城订单通知", "#d71345"));
            data.put("keyword1", new TemplateMessageItem(payMoney, "#d71345"));
            data.put("keyword2", new TemplateMessageItem("原路退回", "#d71345"));
            data.put("keyword3", new TemplateMessageItem("具体到账时间以收到时间为准", "#d71345"));
            data.put("remark", new TemplateMessageItem("点击查看详情进入【我的】-【我的订单】-查看", null));
            accountService.sendWxMessage(templateId, data, openId, urls.getValue() + "/pages/zysc/my/myList#/pages/zysc/my/myList");
        }
        //订单消息
        MessageInfo messageInfo = new MessageInfo();
        messageInfo.setState("4");
        messageInfo.setTitle("订单退款成功");
        messageInfo.setContent("退款金额："+payMoney+"退款方式：原路退回，退款时间：具体到账时间以收到时间为准");
        messageInfo.setUserName(user.getNickName());
        messageInfo.setUserId(userId.toString());
        iMessageService.saveBody(messageInfo);
        if (user.getClientid() != null) {
            pushToSingle("订单退款成功", "退款金额："+payMoney+"退款方式：原路退回，退款时间：具体到账时间以收到时间为准", user.getClientid());
        }
    }

    /**
     * 获取小程序带参二维码
     * @param page 主页面
     * @param scene 参数拼接
     * @param width 二维码宽度
     * @param response 返回照片
     * @return
     */
    @Override
    public void getImg(String page, String scene,String width, HttpServletResponse response){
        InputStream inputStream = getQRFromWechat(page, scene, width);
        //生成二维码图片

        try{
            if(inputStream.available() < 200) {
                byte[] bytes = new byte[inputStream.available()];
                inputStream.read(bytes);
                log.info("生成小程序码失败:{}", new String(bytes, Charset.defaultCharset()));
                response.getOutputStream().write(bytes);
                return;
            }
            response.setContentType("image/png");
            BufferedImage bi = ImageIO.read(inputStream);
            ImageIO.write(bi, "JPG", response.getOutputStream());
        }catch (Exception e){
            e.printStackTrace();
        } finally {
            try {
                response.getOutputStream().flush();
                response.getOutputStream().close();
            } catch (Exception e) {

            }
        }
    }

    @Override
    public String getImagePath(String page, String scene, String width) throws Exception {
        FileOutputStream fos = null;
        try {
            InputStream inputStream = getQRFromWechat(page, scene, width);
            if (inputStream.available() < 200) {
                byte[] bytes = new byte[inputStream.available()];
                inputStream.read(bytes);
                JsonNode jsonNode = JsonUtils.readNode(bytes);
                log.info("生成小程序码失败:{}", jsonNode);
                throw new DescribeException(jsonNode.get("errmsg").asText(), ExceptionEnum.GEN_QR_CODE_ERROR.getCode());
            }
            BufferedImage bi = ImageIO.read(inputStream);
            String filePath = "/file/uploadPath/QR/" + SeqUtils.dateSeq() + ".png";
            String fullPath = rootPath + filePath;
            File file = FileUtils.createFile(fullPath);
            fos = new FileOutputStream(file);
            ImageIO.write(bi, "JPG", fos);
            return filePath;
        } catch (Exception e) {
            log.error("生成微信二维码失败.", e);
            throw new DescribeException(ExceptionEnum.GEN_QR_CODE_ERROR);
        } finally {
            if(fos != null) {
                fos.flush();
                IOUtils.closeQuietly(fos);
            }
        }
    }

    /**
     * 从微信获取小程序分享的二维码
     * @param page
     * @param scene
     * @param width
     * @return
     */
    private InputStream getQRFromWechat(String page, String scene, String width) {
        log.info("生成小程序码图片,page = {}, scene = {}, width = {}", page, scene, width);
        //获取access_token
        String appid = commonRepository.findOne(45).getValue();
        String secret = commonRepository.findOne(46).getValue();
        String url1 = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appid+"&secret="+secret;
        String s = HttpClient.doGet(url1);
        log.info("获取微信token成功:{}", s);
        JSONObject j = JSONObject.parseObject(s);
        String access_token = j.get("access_token").toString();
        //获取二维码数据
        String url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token="+access_token;
        Map<String,Object> map = Maps.newHashMap();
        map.put("scene",scene);
        map.put("page",page);
        map.put("width", width);
        String jsonString = JSON.toJSONString(map);
        InputStream inputStream = sendPostBackStream(url, jsonString);
        return inputStream;
    }

    /**
     * 向指定 URL 发送POST方法的请求
     */
    public static InputStream sendPostBackStream(String url, String param) {
        PrintWriter out = null;
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性
            conn.setRequestProperty("accept", "*/*");
            conn.setRequestProperty("connection", "Keep-Alive");
            conn.setRequestProperty("user-agent",
                    "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)");
            conn.setDoOutput(true);
            conn.setDoInput(true);
            //解决乱码问题
            OutputStreamWriter outWriter =new OutputStreamWriter(conn.getOutputStream(), "utf-8");
            out =new PrintWriter(outWriter);
            // 发送请求参数
            if(StringUtils.isNotBlank(param)) {
                out.print(param);
            }
            // flush输出流的缓冲
            out.flush();
            return conn.getInputStream();
        } catch (Exception e) {
            System.out.println("发送 POST 请求出现异常！"+e);
            e.printStackTrace();
        } finally{
            IOUtils.closeQuietly(out);
        }
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void adjustPromotePoint(AdjustPromotePointReq req) {
        String adminId = LoginUserHolder.getAdminId();
        UserInfo userInfo = userRepository.getUserById(req.getUserId());
        AssertUtil.notNull(userInfo, ExceptionEnum.USER_NOT_FIND);
        // 积分调整处理
        BigDecimal adjustPoint = new BigDecimal(req.getNumber());
        if("GEN".equals(req.getOperation())) {
            userRepository.addPromotePoint(adjustPoint, req.getUserId());
        } else {
            AssertUtil.assertTrue(userInfo.getPromotePointAvailable().compareTo(adjustPoint) >= 0, ExceptionEnum.ADJUST_POINT_NE);
            userRepository.subPromotePoint(adjustPoint, req.getUserId());
        }
        insertRecord(req.getUserId(), req.getOperation(), adjustPoint, req.getRemark(), adminId);
    }

    private PromotePointRecord insertRecord(Long userId, String type, BigDecimal point, String remark, String createBy) {
        String seq = SeqTools.dateSeq();
        PromotePointRecord record = new PromotePointRecord();
        record.setPromoteSeqNo(seq);
        record.setRecordType(type);
        record.setPointAmount(point);
        record.setUserId(userId);
        record.setSceneCode(PPointScene.ADJUST.getCode());

        record.setItemName("管理员调整");
        record.setRemark(remark);
        record.setCreateBy(createBy);
        record.setUpdateBy(createBy);

        promotePointRecordRepository.save(record);
        log.info("插入活动积分记录表记录: {}", JsonUtils.toJsonString(record));
        return record;
    }
}
